﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net.NetworkInformation;

namespace UppityUp
{
    public partial class frmMain : Form
    {
        private Timer tmPingTimer = new Timer() { Enabled = false, Interval = 30000 };
        private String destination = null;
        Ping pinger = new Ping();
        DateTime lastPingAt = DateTime.MinValue;

        private Icon activeIcon, successIcon, inactiveIcon;

        public frmMain()
        {
            InitializeComponent();
        }

        private void frmMain_Load(object sender, EventArgs e)
        {
            hideForm();
            initIcons();
            setNotifyIcon(UppityUpState.Inactive);
            showNotifyIcon();
            tmPingTimer.Tick += new EventHandler(tmPingTimer_Tick);
            pinger.PingCompleted += new PingCompletedEventHandler(pinger_PingCompleted);
        }

        void pinger_PingCompleted(object sender, PingCompletedEventArgs e)
        {
            bool success = true;
            success = !e.Cancelled && e.Error == null && e.Reply != null && e.Reply.Status == IPStatus.Success && e.UserState == destination; // Ensure that this response is regarding current destination
            if (success)
                this.success();
        }

        private void success()
        {
            tmPingTimer.Stop();
            setNotifyIcon(UppityUpState.Success);
            notifyIcon.ShowBalloonTip(int.MaxValue, "The server is up!", String.Format("UppityUp has detected that {0} is now responding!", destination), ToolTipIcon.Info);
        }

        void tmPingTimer_Tick(object sender, EventArgs e)
        {
            sendPing();
            setNotifyIcon(UppityUpState.Active);
        }

        private void hideForm()
        {
            this.ShowInTaskbar = false;
            this.Hide();

        }

        private void showNotifyIcon()
        {
            notifyIcon.Visible = true;
            notifyIcon.ShowBalloonTip(5000, "UppityUp", "Click the icon to set the server to watch.\n\nUppityUp will notify you when the server comes online.", ToolTipIcon.Info);
            notifyIcon.MouseClick += new MouseEventHandler(notifyIconClicked);
        }

        void notifyIcon_BalloonTipClicked(object sender, EventArgs e)
        {
            // Simulate a single left-click on the icon
            MouseEventArgs fakeE = new MouseEventArgs(System.Windows.Forms.MouseButtons.Left, 1, MousePosition.X, MousePosition.Y, 0);
            notifyIconClicked(this, fakeE);
        }

        void notifyIconClicked(object sender, MouseEventArgs e)
        {
            if (e.Button != System.Windows.Forms.MouseButtons.Left) return;
            tmPingTimer.Stop();
            this.Show();
            txtDestination.Text = destination;
            txtDestination.SelectAll();
            txtDestination.Focus();

        }

        private void btnOK_Click(object sender, EventArgs e)
        {
            this.hideForm();
            if (!String.IsNullOrWhiteSpace(txtDestination.Text))
            {
                destination = txtDestination.Text;
                sendPing();
                setNotifyIcon(UppityUpState.Active);
            }
        }

        private void sendPing()
        {
            if (string.IsNullOrWhiteSpace(destination)) return;
            pinger.SendAsyncCancel(); // Cancel old requests
            pinger.SendAsync(destination, destination);
            lastPingAt = DateTime.Now;
            tmPingTimer.Start();
        }

        private void setNotifyIcon(UppityUpState state)
        {
            switch (state)
            {
                case UppityUpState.Inactive:
                    notifyIcon.Icon = this.inactiveIcon;
                    notifyIcon.Text = "UppityUp is inactive.";
                    break;
                case UppityUpState.Active:
                    notifyIcon.Icon = this.activeIcon;
                    notifyIcon.Text = String.Format("Last ping sent at {0:t}.", lastPingAt);
                    break;
                case UppityUpState.Success:
                    notifyIcon.Icon = this.successIcon;
                    notifyIcon.Text = String.Format("The server at {0} is up and responding!", destination);
                    break;

                default:
                    break;
            }
        }


        private void initIcons()
        {
            inactiveIcon = new Icon(typeof(frmMain), "transmit_inactive.ico");
            activeIcon = new Icon(typeof(frmMain), "transmit_go.ico");
            successIcon = new Icon(typeof(frmMain), "success.ico");
        }

        private enum UppityUpState
        {
            Inactive,
            Active,
            Success
        }

        private void mnuSetServer_Click(object sender, EventArgs e)
        {
            notifyIconClicked(mnuSetServer, new MouseEventArgs(System.Windows.Forms.MouseButtons.Left,1,MousePosition.X,MousePosition.Y,0));
        }

        private void mnuExit_Click(object sender, EventArgs e)
        {
            notifyIcon.Dispose();
            inactiveIcon.Dispose();
            activeIcon.Dispose();
            successIcon.Dispose();
            this.Dispose();
        }

        private void frmMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            // User clicked the red x
            // Hide the form without changes
            hideForm();
            e.Cancel = true;
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            hideForm();
        }
    }
}
